﻿using Kingdee.BOS;
using Kingdee.BOS.App;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.BusinessEntity.InformationCenter.PushPlatform.Dto;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Contracts.AI;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Interaction;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Log;
using Kingdee.BOS.Msg;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceFacade.KDServiceFx;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.BOS.WebApi.FormService;
using Kingdee.BOS.WebApi.ServicesStub;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mail;
using System.Xml.Linq;

namespace TZ.PlugIn.FileSrv.CustomApi
{
    /// <summary>
    /// 自定义API
    /// </summary>
    public class TzPurOrderApi : AbstractWebApiBusinessService
    {
        public TzPurOrderApi(KDServiceContext context) : base(context)
        {
        }
        public string AddPurStatues(string sn)
        {
            object apiSave = null;
            // 将JObject转换为字符串，然后反序列化
            //string pars = jsonData.ToString();
            //var request = JsonConvert.DeserializeObject<ContractCallbackRequest>(pars);
            var ctx = KDContext.Session.AppContext;
            if (ctx == null)
            {
                // 会话超时，需重新登录
                throw new Exception("ctx = null,会话超时，需重新登录");
            }
            //string bizId = string.Empty;
            try
            {
                // 直接获取bizId的值
                //bizId = request.bizId;

                // 使用bizId进行业务处理
                if (sn.IsNullOrEmptyOrWhiteSpace())
                {
                    throw new Exception("回调参数：sn不能为空");
                }


            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            IMetaDataService service = ServiceHelper.GetService<IMetaDataService>();
            FormMetadata formMetadata = (FormMetadata)service.Load(ctx, "PUR_PurchaseOrder");
            BusinessInfo info = formMetadata.BusinessInfo;
            DynamicObject csbomMaterial = BusinessDataServiceHelper.LoadSingle(ctx, sn, info.GetDynamicObjectType());//获取指定BOM的实体


            try
            {
                var sql = "";
                DynamicObject Supp = csbomMaterial["SupplierId"] as DynamicObject;
                string supName = Supp == null ? "" : Supp["name"].ToString();//由供应商名称改为简称

                var create = csbomMaterial["CreatorId"] as DynamicObject;
                int CreatorId = create == null ? 0 : Convert.ToInt32(create["id"]);
                string creName = create == null ? "" : create["name"].ToString();

                var FEMail = csbomMaterial["F_RNFK_ProviderEMail"] == null ? "" : csbomMaterial["F_RNFK_ProviderEMail"].GetString();
                var FEMai2 = csbomMaterial["F_RNFK_PROVIDEREMAIL_Q8S"] == null ? "" : csbomMaterial["F_RNFK_PROVIDEREMAIL_Q8S"].GetString();
                DynamicObjectCollection mailList = GetMailist(CreatorId, ctx);

                var DocumentId = csbomMaterial["FDocumentId"].ToString();
                var BillNo = csbomMaterial["BillNo"].ToString();
                int yyfs = Convert.ToInt32(csbomMaterial["FYYFS"]);
                var ErrMsg = "";
                var FilePath = Guid.NewGuid().ToString() + ".PDF";
                var FileName = BillNo + ".PDF";//定义文件名：单据编号为文件名
                FilePath = PathUtils.GetPhysicalPath("TempfilePath", FilePath);//获取金蝶临时目录
                if (!Directory.Exists(FilePath))//目录不存在，则创建目录
                    Directory.CreateDirectory(FilePath);
                FilePath = FilePath + @"\" + FileName;//文件名为单据编号
                var isPost = true;
                Common.GetParams(ctx);
                var Url = string.Format(Common.DownloadUrl, DocumentId);
                Common.GetFile(Url, Common.AppToken, Common.AppSecret, FilePath, ref isPost, ref ErrMsg);
                if (!isPost)
                {
                    throw new Exception(ErrMsg);
                }
                else
                {
                    var InterId = sn;
                    //检查附件名是否已上传过
                    sql = string.Format("SELECT top 1 FID FROM T_BAS_ATTACHMENT WHERE FBILLTYPE = '{0}' AND FINTERID = '{1}' and FATTACHMENTNAME = '{2}'", "PUR_PurchaseOrder", InterId, FileName);
                    var dyExists = DBUtils.ExecuteDynamicObject(ctx, sql);
                    //if (dyExists.Count > 0)
                    //{
                    //    this.View.ShowErrMessage("附件【" + FileName + "】已经存在，不能重复上传");
                    //    return;
                    //}

                    var isUpload = true;//上传成功标识
                    var blockSize = 1024 * 1024; // 分块大小：1M
                    var FileId = string.Empty;
                    using (var fsRead = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        if (fsRead.Length <= 0)
                        {
                            isUpload = false;
                            throw new Exception("上传附件，单据编号【" + BillNo + "】，附件名【" + FileName + "】为空文件");
                        }
                        while (true)
                        {
                            var content = new byte[blockSize];
                            int size = fsRead.Read(content, 0, content.Length);
                            if (size == 0)
                            {
                                isUpload = false;
                                break;
                            }
                            var IsLast = (size != blockSize);
                            var uploadBytes = new byte[size];
                            Array.Copy(content, uploadBytes, size);
                            var SendByte = Convert.ToBase64String(uploadBytes);

                            var JsonData = Common.CreateUploadJson(FileName, "PUR_PurchaseOrder", IsLast, InterId, BillNo, FileId, SendByte);
                            var ReturnMsg = WebApiServiceCall.AttachmentUpload(ctx, JsonData.ToString());
                            var Result = JObject.Parse(JsonUtil.Serialize(ReturnMsg));
                            if (!Convert.ToBoolean(Result["Result"]["ResponseStatus"]["IsSuccess"].ToString()))
                            {
                                //上传失败
                                var ErrorMsg = Common.GetErrMsg(Result);
                                //this.View.ShowErrMessage("上传附件，单据编号【" + BillNo + "】，附件名【" + FileName + "】失败：" + ErrorMsg);
                                isUpload = false;
                                throw new Exception("上传附件，单据编号【" + BillNo + "】，附件名【" + FileName + "】失败：" + ErrorMsg);
                            }
                            else
                            {
                                //上传成功，获取文件id，分多次上传时，首次上传之后必填
                                FileId = Result["Result"]["FileId"].ToString();
                                // 获取客户端临时目录
                                //string clientTempPath = Path.GetTempPath();
                                //string clientFilePath = Path.Combine(clientTempPath, FileName);
                                //AttachmentDownLoad(FileId, clientTempPath, clientFilePath);
                                if (yyfs == 0)
                                {
                                    var param = new
                                    {
                                        IsDeleteEntry = false,
                                        Model = new
                                        {
                                            FID = sn,
                                            F_RNFK_Attachments_83g = new[]
                                        {
                                            new
                                            {
                                                ServerFileName=FileId,
                                                FileName=FileName,
                                            }
                                        },
                                            FisFinished = true
                                        }
                                    };
                                    var data = JsonConvert.SerializeObject(param);
                                    apiSave = WebApiServiceCall.Save(ctx, "PUR_PurchaseOrder", data);
                                }
                                else
                                {
                                    var param = new
                                    {
                                        IsDeleteEntry = false,
                                        Model = new
                                        {
                                            FID = sn,
                                            FisFinished = true
                                        }
                                    };
                                    var data = JsonConvert.SerializeObject(param);
                                    apiSave = WebApiServiceCall.Save(ctx, "PUR_PurchaseOrder", data);
                                }

                                // 附件上传成功后发送邮件
                                if (IsLast && isUpload)
                                {
                                    try
                                    {
                                        // 发送邮件
                                        if (yyfs == 1)
                                        {
                                            SendEmailWithAttachment(ctx, BillNo, FilePath, FileName, supName, creName, FEMail, FEMai2, mailList);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        // 邮件发送失败不影响主流程，记录日志即可
                                        // 这里可以根据需要记录到系统日志
                                        //System.Diagnostics.Debug.WriteLine($"邮件发送失败: {ex.Message}");
                                        Logger.Info("1、我方单签自动发送邮件，错误：", $"{ex.Message}");
                                    }
                                }

                                if (IsLast)
                                    break;
                            }
                        }
                    }
                    if (isUpload)
                    {
                        sql = string.Format("update T_PUR_POORDER set FisDownload = 1 where FBILLNO = '{0}'", BillNo);
                        DBUtils.Execute(ctx, sql);

                    }
                }
            }
            catch (Exception ex)
            {
                //this.View.ShowErrMessage("下载文件异常：" + ex.Message);
                throw new Exception("下载文件异常：" + ex.Message);
            }


            return JsonConvert.SerializeObject(apiSave);
        }

        private DynamicObjectCollection GetMailist(int creatorId, Context ctx)
        {
            string sql = string.Format(@"/*dialect*/ 
            select FNAME,FEMAIL from T_SEC_user where FUSERID={0} ", creatorId);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(ctx, sql);
            return doc;
        }

        private void SendEmailWithAttachment(Context ctx, string billNo, string filePath, string fileName, string supName, string creName, string fEMail, string fEMai2, DynamicObjectCollection mailList)
        {
            // 获取参数设置-基础管理-BOS平台 虚拟邮箱配置
            //SendMailServiceHelper.EmailMessageInfo GetEmailMessageInfoByBosVirtual(Context ctx, long userId = 0);
            //SendMailServiceHelper.GetEmailMessageInfoByBosVirtual(ctx, 0);

            List<string> to = new List<string>();
            if (!fEMail.IsNullOrEmptyOrWhiteSpace())
            {
                to.Add(fEMail);
            }
            if (!fEMai2.IsNullOrEmptyOrWhiteSpace())
            {
                to.Add(fEMail);
            }
            foreach (var obj in mailList)
            {
                var creaMail = obj["FEMAIL"];
                if (!creaMail.IsNullOrEmptyOrWhiteSpace())
                {
                    to.Add(obj["FEMAIL"].ToString());
                }
            }
            //EmailMessageInfo emailInfo = new EmailMessageInfo();
            EmailMessageInfo emailInfo = SendMailServiceHelper.GetEmailMessageInfoByBosVirtual(ctx, 0);
            //设置邮件服务器
            //SetMailServer(emailInfo);
            // 设置邮件标题
            emailInfo.Subject = $"【工作流消息】标准采购订单：{billNo}，供应商：{supName}已完成审批，请关注！(发送人：{creName})";
            // 设置邮件内容
            SetMailBody(emailInfo, billNo, supName);
            // 设置邮件接收人
            emailInfo.To = to;

            // 添加附件
            if (File.Exists(filePath))
            {
                emailInfo.Attachments.Add(filePath);
            }
            try
            {
                //发送邮件
                MailUtils.Sendmail(emailInfo);
            }
            catch (Exception ex)
            {
                Logger.Info("2、我方单签自动发送邮件，错误：", $"{ex.Message}");
            }
        }

        private void SetMailBody(EmailMessageInfo emailInfo, string billNo, string supName)
        {
            emailInfo.Body = "标准采购订单：" + billNo + "，供应商：" + supName + "已完成审批，请关注！";
        }

        private void SetMailServer(EmailMessageInfo emailInfo)
        {
            emailInfo.EnableSSL = true;
            emailInfo.From = "mes@bpw.cn";
            emailInfo.FromName = "金蝶云星空自动邮件";
            emailInfo.IsBodyHtml = true;
            emailInfo.IsMailBCC = false;
            emailInfo.Password = "bpwmz2022";
            emailInfo.Protocol = EmailProtocol.POP3;
            emailInfo.PwdDecode = true;
            emailInfo.SendType = EmailSendType.Default;
            emailInfo.SmtpHost = "61.143.205.219";
            emailInfo.SmtpPort = 25;
            emailInfo.UserName = "mes@bpw.cn";
        }

        /// <summary>
        /// 保存多附件文件
        /// </summary>
        /// <param name="bizId"></param>
        /// <param name="ctx"></param>
        /// <exception cref="NotImplementedException"></exception>
        private string SetAttachments(string bizId, Context ctx, string fileId)
        {
            //创建视图
            IBillView billView = CreateView(ctx, "PUR_PurchaseOrder");
            ((IBillViewService)billView).LoadData();
            DynamicFormViewPlugInProxy eventProxy = billView.GetService<DynamicFormViewPlugInProxy>();
            eventProxy.FireOnLoad();
            billView.Model.Load(bizId);
            //var objModel = billView.Model.DataObject;
            billView.Model.SetItemValueByID("F RNFK Attachments_83g", fileId, 0);//F RNFK Attachments_83g
            //保存单据
            string saveRes = OnlySaveBill(billView, OperateOption.Create(), ctx);
            return saveRes;
        }

        private string OnlySaveBill(IBillView billView, OperateOption saveOption, Context ctx)
        {
            // 设置FormId
            Form form = billView.BillBusinessInfo.GetForm();
            if (form.FormIdDynamicProperty != null)
            {
                form.FormIdDynamicProperty.SetValue(billView.Model.DataObject, form.Id);
            }
            // 调用保存操作
            IOperationResult saveResult = BusinessDataServiceHelper.Save(
                        ctx,
                        billView.BillBusinessInfo,
                        billView.Model.DataObject,
                        saveOption,
                        "Save");
            // 显示处理结果
            if (saveResult == null)
            {
                IOperationResult opResult = new OperationResult();
                opResult.OperateResult.Add(new OperateResult()
                {
                    SuccessStatus = false,
                    Message = "未知原因导致保存失败！",
                    MessageType = Kingdee.BOS.Core.DynamicForm.MessageType.Warning,
                    Name = "保存",
                    PKValue = 0,
                });
                //operationResult.MergeResult(opResult);
                //billView.ShowErrMessage("未知原因导致保存失败！");
                return "未知原因导致保存失败！";
            }
            else if (saveResult.InteractionContext != null && saveResult.InteractionContext.Option.GetInteractionFlag().Count > 0)
            {
                // 保存失败，需要用户确认问题
                //InteractionUtil.DoInteraction(billView, saveResult, saveOption,
                //    new Action<FormResult, IInteractionResult, OperateOption>((formResult, opResult, option) =>
                //    {
                //        // 用户确认完毕，重新调用保存处理
                //        SaveBill(billView, option, ctx);
                //    }));
                return "保存附件失败，需要用户确认问题";
            }
            return "保存附件成功";
        }

        /// <summary>
        /// 保存、提交、审核单据
        /// </summary>
        /// <param name="billView">视图</param>
        /// <param name="saveOption">保存选项</param>
        /// <param name="ctx">上下文</param>
        public static void SaveBill(IBillView billView, OperateOption saveOption, Context ctx)
        {
            // 设置FormId
            Form form = billView.BillBusinessInfo.GetForm();
            if (form.FormIdDynamicProperty != null)
            {
                form.FormIdDynamicProperty.SetValue(billView.Model.DataObject, form.Id);
            }

            // 调用保存操作
            IOperationResult saveResult = BusinessDataServiceHelper.Save(
                        ctx,
                        billView.BillBusinessInfo,
                        billView.Model.DataObject,
                        saveOption,
                        "Save");
            // 显示处理结果
            if (saveResult == null)
            {
                billView.ShowErrMessage("未知原因导致保存失败！");
                return;
            }
            else if (saveResult.IsSuccess == true)
            {// 保存成功，直接显示
             //this.View.ShowOperateResult(saveResult.OperateResult);

                object[] pkArray = (from p in saveResult.SuccessDataEnity select p[0]).ToArray();

                var submitResult = BusinessDataServiceHelper.Submit(ctx, billView.BillBusinessInfo, pkArray, "Submit", OperateOption.Create());
                if (submitResult.IsSuccess)
                {
                    var auditResult = BusinessDataServiceHelper.Audit(ctx, billView.BillBusinessInfo, pkArray, OperateOption.Create());
                    if (auditResult.IsSuccess)
                    {
                        billView.ShowOperateResult(auditResult.OperateResult);
                    }
                }
            }
            else if (saveResult.InteractionContext != null && saveResult.InteractionContext.Option.GetInteractionFlag().Count > 0)
            {
                // 保存失败，需要用户确认问题
                InteractionUtil.DoInteraction(billView, saveResult, saveOption,
                    new Action<FormResult, IInteractionResult, OperateOption>((formResult, opResult, option) =>
                    {
                        // 用户确认完毕，重新调用保存处理
                        SaveBill(billView, option, ctx);
                    }));
            }
            // 保存失败，显示错误信息
            if (saveResult.IsShowMessage)
            {
                saveResult.MergeValidateErrors();
                billView.ShowOperateResult(saveResult.OperateResult);
                return;
            }
        }

        /// <summary>
        /// 初始化视图
        /// </summary>
        /// <param name="ctx">上下文</param>
        /// <param name="formId">单据标识</param>
        /// <returns></returns>
        public static IBillView CreateView(Context ctx, string formId)
        {
            FormMetadata meta = MetaDataServiceHelper.Load(ctx, formId) as FormMetadata;
            Form form = meta.BusinessInfo.GetForm();
            Type type = Type.GetType("Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web");
            var billView = (IDynamicFormViewService)Activator.CreateInstance(type);
            BillOpenParameter openParam = CreateOpenParameter(meta, ctx);
            var provider = form.GetFormServiceProvider();
            billView.Initialize(openParam, provider);
            return billView as IBillView;
        }

        /// <summary>
        /// 初始化参数
        /// </summary>
        /// <param name="meta"></param>
        /// <param name="ctx"></param>
        /// <returns></returns>
        public static BillOpenParameter CreateOpenParameter(FormMetadata meta, Context ctx)
        {
            Form form = meta.BusinessInfo.GetForm();
            BillOpenParameter openParam = new BillOpenParameter(form.Id, meta.GetLayoutInfo().Id);
            openParam.Context = ctx;
            openParam.ServiceName = form.FormServiceName;
            openParam.PageId = Guid.NewGuid().ToString();
            openParam.FormMetaData = meta;
            openParam.Status = OperationStatus.ADDNEW;
            openParam.PkValue = null;
            openParam.CreateFrom = CreateFrom.Default;
            openParam.GroupId = "";
            openParam.ParentId = 0;
            openParam.DefaultBillTypeId = "";
            openParam.DefaultBusinessFlowId = "";
            openParam.SetCustomParameter("ShowConfirmDialogWhenChangeOrg", false);
            List<AbstractDynamicFormPlugIn> plugs = form.CreateFormPlugIns();
            openParam.SetCustomParameter(FormConst.PlugIns, plugs);
            PreOpenFormEventArgs args = new PreOpenFormEventArgs(ctx, openParam);
            foreach (var plug in plugs)
            {
                plug.PreOpenForm(args);
            }
            if (args.Cancel == true)
            {
                // 不理会插件的诉求，继续....
            }
            return openParam;
        }

        private void AttachmentDownLoad(string fileId, string filePath2, string clientFilePath, string fileName, Kingdee.BOS.Context ctx)
        {
            try
            {
                // 构造下载请求数据
                JObject downloadRequest = new JObject
        {
            { "FileId", fileId },
            { "StartIndex", 0 }
        };

                // 调用WebApiServiceCall.AttachmentDownLoad方法下载文件
                var downloadResult = WebApiServiceCall.AttachmentDownLoad(ctx, downloadRequest.ToString());

                // 检查返回结果是否为字符串（可能包含错误信息）
                if (downloadResult is string stringResult)
                {
                    // 尝试解析字符串为JSON
                    try
                    {
                        JObject dResult = JObject.Parse(stringResult);
                        ProcessDownloadResult(dResult, clientFilePath, fileName);
                    }
                    catch (JsonReaderException)
                    {
                        // 如果不是JSON，可能是错误消息
                        //this.View.ShowMessage($"下载失败: {stringResult}");
                        throw new Exception($"下载失败: {stringResult}");
                    }
                }
                else
                {
                    // 如果已经是对象，直接序列化再解析
                    string jsonResponse = JsonUtil.Serialize(downloadResult);
                    JObject dResult = JObject.Parse(jsonResponse);
                    ProcessDownloadResult(dResult, clientFilePath, fileName);
                }
            }
            catch (Exception ex)
            {
                //this.View.ShowMessage($"下载过程中发生错误: {ex.Message}");
                throw new Exception($"下载过程中发生错误: {ex.Message}");
            }
        }

        private void ProcessDownloadResult(JObject dResult, string clientFilePath, string fileName)
        {
            if (dResult != null && dResult["Result"] != null)
            {
                var result = dResult["Result"];
                if (result["ResponseStatus"]?["IsSuccess"]?.ToObject<bool>() == true)
                {
                    // 获取文件内容并保存到本地
                    string fileContent = result["FilePart"].ToString();
                    File.WriteAllBytes(clientFilePath, Convert.FromBase64String(fileContent));
                    Console.WriteLine("文件下载成功，保存路径：" + clientFilePath);

                    // 生成文件的下载地址(Url: http:\\localhost\K3Cloud\...\xxx.xlsx)

                    var fileUrl = PathUtils.GetServerPath("TempfilePath", fileName);
                    var appUrl = PathUtils.GetAppCallingPath();

                    var showParameter = new DynamicFormShowParameter();

                    showParameter.FormId = "BOS_FileDownLoad";

                    showParameter.OpenStyle.ShowType = ShowType.Modal;

                    showParameter.CustomParams.Add("url", fileUrl);

                    //this.View.ShowForm(showParameter);
                }
                else
                {
                    string errorMessage = result["ResponseStatus"]?["Errors"]?.ToString() ?? "未知错误";
                    //this.View.ShowMessage($"文件下载失败: {errorMessage}");
                }
            }
            else
            {
                //this.View.ShowMessage("下载结果为空或格式不正确，请检查请求参数。");
            }
        }
    }
}
